from flask import Flask
from Config import config_map
from flask_sqlalchemy import SQLAlchemy
from flask_session import Session
from flask_wtf import CSRFProtect
import redis
import logging
from logging.handlers import RotatingFileHandler
from IHOME.utils.commons import ReConverter

# 数据库
db = SQLAlchemy()
# 创建redis连接对象
redis_store = None

# 使用wtf提供的csrf保护机制
csrf = CSRFProtect()

# 设置日志的记录等级
# logging.error() 错误级别
# logging.warning() 警告级别
# logging.info() 消息提示级别
# logging.debug()  调试级别
logging.basicConfig(level=logging.DEBUG)  # 调试Debug级别
# 项目处在开发模式时，Debug=True 会覆盖掉设置的日志记录等级直接显示Debug级别的日志
# 创建日志记录器，指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 10, backupCount=10, encoding="utf-8")
# 创建日志记录的格式               日志等级   输入日志信息的文件名 行数     日志信息
formatter = logging.Formatter("%(levelname)s %(filename)s:%(lineno)d %(message)s")
# 为刚创建的日志记录器设置日志记录格式
file_log_handler.setFormatter(formatter)
# 为全局的日志工具对象(flask app 使用的)添加日志记录器
logging.getLogger().addHandler(file_log_handler)


# 工厂模式
def creat_app(config_name):
    """
    创建flask的应用对象
    :param config_name: str  配置模式的模式名字  ("develop", "product")
    :return:
    """
    app = Flask(__name__)
    # 根据配置模式的名字获取配置参数的类
    config_class = config_map.get(config_name)
    # 导入配置信息
    app.config.from_object(config_class)
    # 使用app初始化db
    db.init_app(app)
    # 初始化redis工具
    global redis_store
    redis_store = redis.StrictRedis(host=config_class.REDIS_HOST, port=config_class.REDIS_PORT, decode_responses=True)
    # 此处decode_responses = True参数的意义是让取出的redis缓存数据直接为str类型。如果不加这个参数，
    # redis取出的缓存数据默认为bytes类型，和用户输入的str类型无法比较，后期需要为每条取出的redis缓存数据手动添加decode()解码，
    # 非常麻烦。所以在redis初始设置中添加这个参数省去后期手动decode()解码，另外如果不加这个参数，
    # 后期很多针对redis数据的存取时会先把缓存数据设置为None然后进行后续操作，而None类型无法进行decode()解码，
    # 那么你手动添加的对redis缓存数据的decode()解码会报错，不利于代码的编写和运行，所以这个参数虽然并未规定是必加参数，
    # 但是为了代码的优化还是非常有必要添加的。
    Session(app)
    # 为flask补充csrf防护
    csrf.init_app(app)
    # 为flask添加自定义的转换器
    app.url_map.converters["re"] = ReConverter
    # 注册蓝图
    from IHOME import api_1_0
    app.register_blueprint(api_1_0.api, url_prefix="/api/v1.0")
    # 注册提供静态文件的蓝图
    from IHOME import web_html
    app.register_blueprint(web_html.html)
    return app
